package com.mall.common.util;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.DigestUtils;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.Map;

/**
 * JWT工具类
 */
@Slf4j
public class JwtUtil {
    
    /**
     * 生成JWT Token
     *
     * @param claims    载荷信息
     * @param secret    密钥
     * @param expiration 过期时间（毫秒）
     * @return Token字符串
     */
    public static String generateToken(Map<String, Object> claims, String secret, Long expiration) {
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        Date expirationDate = new Date(System.currentTimeMillis() + expiration);
        
        return Jwts.builder()
                .setClaims(claims)
                .signWith(key)
                .setExpiration(expirationDate)
                .compact();
    }
    
    /**
     * 解析JWT Token
     *
     * @param token  Token字符串
     * @param secret 密钥
     * @return Claims对象
     * @throws ExpiredJwtException     Token已过期
     * @throws UnsupportedJwtException 不支持的Token
     * @throws MalformedJwtException   Token格式错误
     * @throws SignatureException      签名异常
     * @throws IllegalArgumentException 参数异常
     */
    public static Claims parseToken(String token, String secret) 
            throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException {
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        JwtParser parser = Jwts.parserBuilder()
                .setSigningKey(key)
                .build();
        return parser.parseClaimsJws(token).getBody();
    }
    
    /**
     * 验证JWT Token是否有效
     *
     * @param token  Token字符串
     * @param secret 密钥
     * @return 是否有效
     */
    public static boolean validateToken(String token, String secret) {
        try {
            parseToken(token, secret);
            return true;
        } catch (ExpiredJwtException e) {
            log.warn("Token已过期: {}", e.getMessage());
        } catch (UnsupportedJwtException e) {
            log.warn("不支持的Token: {}", e.getMessage());
        } catch (MalformedJwtException e) {
            log.warn("Token格式错误: {}", e.getMessage());
        } catch (SignatureException e) {
            log.warn("Token签名异常: {}", e.getMessage());
        } catch (IllegalArgumentException e) {
            log.warn("Token参数异常: {}", e.getMessage());
        }
        return false;
    }
    
    /**
     * 判断Token是否已过期
     *
     * @param token  Token字符串
     * @param secret 密钥
     * @return 是否已过期
     */
    public static boolean isTokenExpired(String token, String secret) {
        try {
            Claims claims = parseToken(token, secret);
            return claims.getExpiration().before(new Date());
        } catch (ExpiredJwtException e) {
            return true;
        } catch (Exception e) {
            log.warn("判断Token是否过期时发生异常: {}", e.getMessage());
            return false;
        }
    }
    
    /**
     * 验证密码
     *
     * @param rawPassword 明文密码
     * @param encodedPassword 加密后的密码
     * @return 是否匹配
     */
    public static boolean validatePassword(String rawPassword, String encodedPassword) {
        // 使用MD5加密进行密码验证
        String md5Password = DigestUtils.md5DigestAsHex(rawPassword.getBytes());
        return md5Password.equals(encodedPassword);
    }
}